
#include "general.h"

/* Since the combo box has auto alphabetically arranging, the internal
   code does not have to match the alphabetical nunbering. This contains
   the table of combo and internal tube numbers. */
static int poly_combo[NO_PLATSOLIDS];

static PROPSHEETPAGE *ps;

static HWND hPolyhedra;		// Polyhedra selection combo
static HWND hSpeed;			// Slider Speed Control
static HWND hI;				// Text box for I
static HWND hItxt;			// Static for I
static HWND hR;				// Text box for R
static HWND hRtxt;			// Static in front of the R textbox
static HWND hUseRatio;		// Check-box for the Schlicker Kunnen ratio
static HWND hIterative;		// Use the iterative algorithm to draw

static HWND hObjs;			// The number of objects in the polyhedra
static HWND hChange;		// If we should change when tubes are random
static HWND hCycles;		// Number of cycles after which to change
static HWND hCyclesStatic;	// The static that says cycles

extern int cpolygon;

void DisableCycles()
{
	EnableWindow (hCycles, false);
	EnableWindow (hCyclesStatic, false);
}

void EnableCycles()
{
	EnableWindow (hCycles, true);
	EnableWindow (hCyclesStatic, true);
}

void DisableAll()
{
	EnableWindow (hI, false);
	EnableWindow (hItxt, false);
	EnableWindow (hR, false);
	EnableWindow (hRtxt,false);
	EnableWindow (hUseRatio, false);
	EnableWindow (hObjs, false);

	EnableWindow (hChange, true);
	if (change)
	{
		EnableCycles();
	}
	else
	{
		DisableCycles();
	}
}

void EnableAll ()
{
	EnableWindow (hI, true);
	EnableWindow (hItxt, true);
	if (!useratio)
	{
		EnableWindow (hR, true);
		EnableWindow (hRtxt,true);
	}
	EnableWindow (hUseRatio, true);
	EnableWindow (hObjs, true);

	EnableWindow (hChange, false);
	EnableWindow (hCycles, false);
	EnableWindow (hCyclesStatic, false);
}

void SetValues ()
{
	if (cpolygon == 5)
	{
		SendMessage (hObjs, WM_SETTEXT, 0, (LPARAM)"Not Available");
		return;
	}

	char buffer[100];
	sprintf_s (buffer, 
		"Polyhedra contains %u objects, %u faces and %u points.", 
		NumObjs   (cpolygon, cur_i),
		NumFaces  (cpolygon, cur_i),
		NumPoints (cpolygon, cur_i));
	SendMessage (hObjs, WM_SETTEXT, 0, (LPARAM)buffer);
}

void SetRatio ()
{
	cur_r = SchlickerKunnen(cpolygon);
	
	char buffer[5];
	sprintf_s (buffer, "%.2f", cur_r);
	SendMessage (hR, WM_SETTEXT, 0, (LPARAM)buffer);
}

int AddComboEntry (HWND hCombo, UINT rID)
{
	char cstr[256];

	LoadString (hMainInstance, rID, cstr, sizeof(cstr));
	return SendMessage (hCombo, CB_ADDSTRING, 0, 
			(LPARAM)(LPCSTR)cstr);
}

void AddTubeEntries (HWND hCombo)
{
	poly_combo[0] = AddComboEntry (hCombo, IDS_TETRAHEDRON);
	poly_combo[1] = AddComboEntry (hCombo, IDS_OCTAHEDRON);
	poly_combo[2] = AddComboEntry (hCombo, IDS_CUBE);
	poly_combo[3] = AddComboEntry (hCombo, IDS_ICOSAHEDRON);
	poly_combo[4] = AddComboEntry (hCombo, IDS_DODECAHEDRON);
	poly_combo[5] = AddComboEntry (hCombo, IDS_RANDOM);

	SendMessage (hCombo, CB_SETCURSEL, (WPARAM)poly_combo[cpolygon], 0);
}

// This is a callback function to the general tab of the settings
// property page
BOOL APIENTRY ConfigureSettingsGeneral (HWND hDlg, 
	 UINT message, WPARAM wParam, LPARAM lParam)
{
	const int bufsize = 5;
	char buffer[bufsize];

	switch (message)
	{
	case WM_INITDIALOG:
		ps = (PROPSHEETPAGE*)lParam;

		hPolyhedra  = GetDlgItem (hDlg, IDC_PLATSOLID);
		hSpeed  = GetDlgItem (hDlg, IDC_SPEED);
		hI = GetDlgItem (hDlg, IDC_I);
		hItxt = GetDlgItem (hDlg, IDC_ITXT);
		hR = GetDlgItem (hDlg, IDC_R);
		hRtxt = GetDlgItem (hDlg, IDC_RTXT);
		hUseRatio = GetDlgItem (hDlg, IDC_USERATIO);
		hIterative = GetDlgItem (hDlg, IDC_ITERATIVE);
		
		hChange = GetDlgItem (hDlg, IDC_CHANGE);
		hCycles = GetDlgItem (hDlg, IDC_CYCLES);
		hCyclesStatic = GetDlgItem (hDlg, IDC_CYCLES_STATIC);

		hObjs = GetDlgItem (hDlg, IDC_OBJS);
			// Make it accept only one digit number
		SendMessage (hI, EM_SETLIMITTEXT, (WPARAM)1, (LPARAM)0);

			// Insert the names onto the combo box
		AddTubeEntries (hPolyhedra);
		
		return TRUE;
		break;

	case WM_NOTIFY:
		switch ( ( (NMHDR*)lParam ) -> code)
		{
		case PSN_SETACTIVE:
			SendMessage (hSpeed, TBM_SETRANGE, 0, MAKELONG(SPEED_MIN,
				SPEED_MAX));
			SendMessage (hSpeed, TBM_SETPOS, 0, INC_VALUE);
			SendMessage (hSpeed, TBM_SETTICFREQ, (SPEED_MIN-SPEED_MAX)/
				SPEED_NOTICS, 0);

			sprintf_s (buffer, "%d", cur_i);
			SendMessage (hI, WM_SETTEXT, 0, (LPARAM)buffer);
			sprintf_s (buffer, "%.2f", cur_r);
			SendMessage (hR, WM_SETTEXT, 0, (LPARAM)buffer);
			sprintf_s (buffer, "%d", cycles);
			SendMessage (hCycles, WM_SETTEXT, 0, (LPARAM)buffer);

			if (useratio)
			{
				SetRatio();
				EnableWindow (hR, false);
				EnableWindow (hRtxt,false);
				SendMessage (hUseRatio, BM_SETCHECK, useratio, 0);
			}

			if (iterative)
			{
				SendMessage (hIterative, BM_SETCHECK, iterative, 0);
			}

			SendMessage (hChange, BM_SETCHECK, change, 0);

			if (cpolygon == 5)
			{
				DisableAll();
			}
			else
			{
				EnableAll();
			}
			SetValues();

			return TRUE;
			break;

		case PSN_APPLY:
			SaveGeneralSettings();
			SetWindowLong (hDlg, DWL_MSGRESULT, TRUE);
			break;

		case PSN_KILLACTIVE:
				// Get the scaling value out of the edit boxes
			SendMessage (hI, WM_GETTEXT, (WPARAM)bufsize, 
				(LPARAM)buffer);
			cur_i = atoi (buffer);
			SendMessage (hR, WM_GETTEXT, (WPARAM)bufsize, 
				(LPARAM)buffer);
			cur_r = (float)atof (buffer);
			SendMessage (hCycles, WM_GETTEXT, (WPARAM)bufsize,
				(LPARAM)buffer);
			cycles = atoi (buffer);
			if (cycles < 1)
				cycles = 1;

				// Don't let the scaling get out of hand
			if (cur_i < 0)
				cur_i = 0;
			if (cur_r <= 0.0f)
				cur_r = 0.01f;

			if (SendMessage (hIterative, BM_GETCHECK, 0, 0) == 
					BST_CHECKED)
				iterative = true;
			else
				iterative = false;
			
			SetWindowLong (hDlg, DWL_MSGRESULT, FALSE);
			break;

		default:
			break;
		}
		break;

	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDC_PLATSOLID:
			switch (HIWORD(wParam))
			{
			case CBN_SELCHANGE:
				int new_sel, i;
				hPolyhedra = GetDlgItem (hDlg, IDC_PLATSOLID);
				new_sel = SendMessage (hPolyhedra, CB_GETCURSEL, 0, 0);
				
				for (i=0; i<NO_PLATSOLIDS; i++)
				{
					if (new_sel == poly_combo[i])
					{
						cpolygon = i;
					}
				}

				if (cpolygon == 5)
				{
					DisableAll();
				}
				else
				{
					EnableAll();
				}

				SetValues();

				if (useratio)
				{
					SetRatio();
				}
				break;
			}
			break;
		case IDC_I:
			switch (HIWORD(wParam))
			{
			case EN_CHANGE:
				const int bufsize = 2;
				char buffer[bufsize];
				SendMessage (hI, WM_GETTEXT, (WPARAM)bufsize, 
					(LPARAM)buffer);
				cur_i = atoi (buffer);
				SetValues();
				break;
			}
			break;
		case IDC_CHANGE:
			switch (HIWORD(wParam))
			{
			case BN_CLICKED:
				if (SendMessage (hChange, BM_GETCHECK, 0, 0) == BST_CHECKED)
				{
					change = true;
					EnableCycles();
				}
				else
				{
					change = false;
					DisableCycles();
				}
				break;
			}
			break;
		case IDC_USERATIO:
			switch (HIWORD(wParam))
			{
			case BN_CLICKED:
				if (SendMessage (hUseRatio, BM_GETCHECK, 0, 0) == 
					BST_CHECKED)
				{
					SetRatio();
					EnableWindow (hR, false);
					EnableWindow (hRtxt,false);
					useratio = true;
				}
				else
				{
					EnableWindow (hR, true);
					EnableWindow (hRtxt, true);
					useratio = false;
				}
				break;
			}
			break;
		default:
				break;
		}
		break;

	case WM_HSCROLL:
		if (lParam == (LPARAM)hSpeed)
		{
			INC_VALUE = (SendMessage (hSpeed, TBM_GETPOS, 
				0, 0));
			return TRUE;
			break;
		}
	}

	return FALSE;
}